import emitInstance from "../eventEmitter";

const publicConfig = {
    baseUrl: '',
    firstChapterUri: '',
    chapterNameSelecter: '.bookname h1',
    chapterContentSelecter: '#content',
    nextChapterSelecter: '.next',
    chapterReplaceList: [] as { test: RegExp; target: string; }[],
    chapterSliceTextList: [] as string[],
};
const setActiveChapter = (str:string) => {
    emitInstance.emit('__set_active_chapter__', str);
}
const addComplateCount = (status:boolean) => {
    emitInstance.emit('__add_complate_count__', status);
}
function request(url:string) {
    return window.electron.request(publicConfig.baseUrl + url);
}
const hideDom = document.createElement('div');
function getEveryPage(url:string) {
    setActiveChapter(url)
    return request(url).then(res => {
        // console.log('url,',url,res);
        setActiveChapter('')
        // const charset = res.match(/charset=([\w-]+)/i)?.pop();

        let startIndex = res.indexOf('<body');
        let endIndex = res.indexOf('</body>');
        if (startIndex === -1) {
            return null;
        }
        if (endIndex === -1) {
            endIndex === undefined;
        }
        startIndex = startIndex + 6;
        const data = res.slice(startIndex, endIndex);
        hideDom.innerHTML = data;
        const titleDom = hideDom.querySelector(publicConfig.chapterNameSelecter);
        const nextDom = hideDom.querySelector(publicConfig.nextChapterSelecter);
        const contentDom = hideDom.querySelector(publicConfig.chapterContentSelecter);
        if (!titleDom || !contentDom) {
            return null;
        }
        let title = titleDom.textContent!;
        let content = publicConfig.chapterReplaceList.reduce((t, v) => t.replace(v.test, v.target), contentDom.innerHTML);
        let sliceIndex;
        content = publicConfig.chapterSliceTextList.reduce((t, v) => t.slice(0, (sliceIndex = t.indexOf(v)) !== -1 ? sliceIndex : undefined), content);
        addComplateCount(true);
        hideDom.innerHTML = '';
        // if (charset) {
        //     const encoder = new TextEncoder();
        //     const decoder = new TextDecoder(charset);
        //     console.log('charset',title);
        //     return {
        //         title: decoder.decode(encoder.encode(title)),
        //         content: decoder.decode(encoder.encode(content)) + '\n\n',
        //         nextUri: nextDom ? nextDom.getAttribute('href').replace(publicConfig.baseUrl, '') : ''
        //     }
        // }
        return {
            title,
            content: content + '\n\n',
            nextUri: nextDom ? nextDom!.getAttribute('href')!.replace(publicConfig.baseUrl, '') : ''
        };
    }).catch(err => {
        setActiveChapter('')
        addComplateCount(false);
        return null;
    })
}
async function* getChapter(uri:string, chapterList:string[] = [], charpterData:Record<string,string> = {}):AsyncGenerator<string, {
    chapterList:string[]; charpterData:Record<string,string>
}|null, boolean> {
    if (!uri) {
        return {
            chapterList,
            charpterData
        }
    }
    const res = await getEveryPage(uri);
    if (!res) {
        return {
            chapterList,
            charpterData
        }
    }
    const { title, content, nextUri } = res;
    if (uri === publicConfig.firstChapterUri) {
        const isContinue = yield title + '\n\n    ' + content;
        if (!isContinue) {
            return null;
        }
    }
    if (chapterList.includes(title)) {
        if(!charpterData[title].includes(content)){
            charpterData[title] += ('    ' + content);
        }
    } else {
        chapterList.push(title);
        charpterData[title] = '\n\n    ' + content;
    }

    if (nextUri) {
        await getChapter(nextUri, chapterList, charpterData).next();
    }
    return {
        chapterList,
        charpterData
    }
}
async function* getBook(
    firstChapterUrl:string,
    {
        chapterNameSelecter = '.bookname h1',
        chapterContentSelecter = '#content',
        nextChapterSelecter = '.next',
        chapterReplaceList = [
            {
                test: /<a.{1,}<\/a>/g,
                target: ''
            },
            {
                test: /<script.{1,}<\/script>/g,
                target: ''
            },
            {
                test: /&nbsp;/g,
                target: ' '
            },
            {
                test: /(<p>)|( {1,})/g,
                target: ''
            },
            {
                test: /\t/g,
                target: ' '
            },
            {
                test: /<br\/?>/g,
                target: '\n'
            },
            {
                test: /<\/p>/g,
                target: '\n\n    '
            },
            {
                test: /\n{1,}/g,
                target: '\n\n    '
            },
            {
                test: /^\n{1,} {0,}/i,
                target: ''
            },
            {
                test: /\n\n    $/i,
                target: ''
            },
        ],
        chapterSliceTextList = ['(本章未完,请翻页)'],
    }
):AsyncGenerator<string> {
    if (!firstChapterUrl) {
        return null;
    }
    const urls = new URL(firstChapterUrl);
    publicConfig.baseUrl = urls.origin;
    publicConfig.firstChapterUri = urls.pathname;
    publicConfig.chapterNameSelecter = chapterNameSelecter;
    publicConfig.chapterContentSelecter = chapterContentSelecter;
    publicConfig.nextChapterSelecter = nextChapterSelecter;
    publicConfig.chapterReplaceList = chapterReplaceList;
    publicConfig.chapterSliceTextList = chapterSliceTextList;
    const its = getChapter(publicConfig.firstChapterUri);
    const { value } = await its.next();
    const isContinue = yield value as unknown as string;
    const { value: chapterSource } = await its.next(isContinue || false)
    if (!chapterSource || typeof chapterSource === 'string') {
        return;
    }
    const { chapterList, charpterData } = chapterSource;

    const text = chapterList.reduce((t, v) => t + v + charpterData[v], '')
    return text;
}

export default getBook;

